from Base import *
from Header import *


class CCtrlFuncInfo(object):
    _gType=CONTROL_FUNCTION_NONE
    def __init__(self):
        self._successor=0
        self._type = self._gType

    def SetSuccessor(self, successor):
        self._successor=successor

    def AddInfo(self, ctrlFuncEle):
        self._type = ctrlFuncEle._function
        if self._type in ctrlFuncEle._gFuncTypeNameDict:
            item = ctrlFuncEle._subList[ctrlFuncEle._gNameCtrlFunc]
            item._infoStr = ctrlFuncEle._gFuncTypeNameDict[self._type]
        else:
            ctrlFuncEle._errStr = "Invalid Control Function"

        if self._successor != 0:
            self._successor.AddInfo(ctrlFuncEle)

class CCtrlFuncInfoSvt(CCtrlFuncInfo):
    _gType=CONTROL_FUNCTION_SVT
    _gMaskUnit = 0x0F

    _gUnitStrDict = {0:"Seconds", 1:"Minutes", 2:"Hours"}

    def __init__(self):
        super(CCtrlFuncInfoSvt, self).__init__()

    def AddInfo(self, ctrlFuncEle):
        if(ctrlFuncEle._function == self._gType):
            super(CCtrlFuncInfoSvt, self).AddInfo(ctrlFuncEle)
            #this is SVT func
            item = ctrlFuncEle._subList[ctrlFuncEle._gNameParam1]
            unit = ctrlFuncEle._parameter1 & self._gMaskUnit
            if unit in self._gUnitStrDict:
                item._infoStr = "Unit is <" + self._gUnitStrDict[unit] + ">"
            else:
                item._errStr = "Invalid Unit"

            item = ctrlFuncEle._subList[ctrlFuncEle._gNameParam2]
            interval = ctrlFuncEle._parameter2
            item._infoStr = "Interval is <"  + DATA_FORMAT.format(interval) + ">"
        else:
            if self._successor != 0:
                self._successor.AddInfo(ctrlFuncEle)

def AddCtrlFuncResponseChain(fn):
    def new(self,*args):
        cfDefault = CCtrlFuncInfo()

        cfSvt = CCtrlFuncInfoSvt()
        cfSvt.SetSuccessor(cfDefault)
        return fn(self, successor=cfSvt)
    return new


class CControlFunctionElement(CInfoElement):
    _gName = "Control Function Element"
    _gNameCtrlFunc = "Control Function"
    _gNameParam1 = "Parameter_1"
    _gNameParam2 = "Parameter_2"

    _gEleLength = 3

    _gFuncTypeNameDict = {CONTROL_FUNCTION_SVT : "Vehicle Tracking Function",
                          CONTROL_FUNCTION_GEO : "Geo-Fence Function",
                          CONTROL_FUNCTION_SPD : "Speed Alert Function",
                          CONTROL_FUNCTION_RDC : "Remote door locks Function",
                          CONTROL_FUNCTION_MAN : "Maintenance Alert Function",
                          CONTROL_FUNCTION_MIL : "MIL Nofication Function",
                          CONTROL_FUNCTION_ALM : "Alarm Nofication Function"}

    @AddCtrlFuncResponseChain
    def __init__(self, name=_gName, successor=0):
        super(CControlFunctionElement, self).__init__(name)
        self._function = -1
        self._parameter1 = -1
        self._parameter2 = -1

        #this is response chain, it's used to add different informantion
        #depend on different control function type
        self._successor = successor

        self._hlColor = 'white_on_magenta'

    def GetFunction(self):
        return self._function


    def InitSubItem(self):
        name = self._gNameHeader
        item = CEleHeader(name, recommendedLen = self._gEleLength)
        self._subList[name] = item
        self._nameList.append(name)

        name = self._gNameCtrlFunc
        item = CItem(name)
        self._subList[name] = item
        self._nameList.append(name)

        name = self._gNameParam1
        item = CItem(name)
        self._subList[name] = item
        self._nameList.append(name)

        name = self._gNameParam2
        item = CItem(name)
        self._subList[name] = item
        self._nameList.append(name)


    def ParseElement(self, dataStr):
        self._function = dataStr.GetByte()
        item = self._subList[self._gNameCtrlFunc]
        item._rawStr = HEX_DATA_FORMAT.format(self._function)

        self._parameter1 = dataStr.GetByte()
        item = self._subList[self._gNameParam1]
        item._rawStr = HEX_DATA_FORMAT.format(self._parameter1)

        self._parameter2 = dataStr.GetByte()
        item = self._subList[self._gNameParam2]
        item._rawStr = HEX_DATA_FORMAT.format(self._parameter2)

        if self._successor != 0:
            self._successor.AddInfo(self)

        return

